

#include "EventLoopThread.hpp"
#include "EventLoop.hpp"

namespace zephyr {

EventLoopThread::EventLoopThread(const ThreadInitCallback &cb, const std::string &name)
    : m_loop(nullptr)
    , m_exiting(false)
    , m_thread(std::bind(&EventLoopThread::threadFunc, this), name)
    , m_mtx()
    , m_cond()
    , m_callback(cb) {}


EventLoopThread::~EventLoopThread() {
    m_exiting = true;
    if (m_loop != nullptr) {
        m_loop->quit();
        m_thread.join();
    }
}

EventLoop *EventLoopThread::startLoop() {
    m_thread.start();

    EventLoop *loop = nullptr;
    { // 等待线程函数执行完m_callback 并为m_loop分配变量
        std::unique_lock<std::mutex> lock(m_mtx);
        m_cond.wait(lock, [this]() {
            return m_loop != nullptr;
        });
        loop = m_loop;
    }
    return loop;
}

void EventLoopThread::threadFunc() {
    EventLoop loop;
    if (m_callback) {
        m_callback(&loop);
    }
    {
        std::unique_lock<std::mutex> lock(m_mtx);
        m_loop = &loop;
        m_cond.notify_one();
    }

    loop.loop(); // 开启loop
    std::unique_lock<std::mutex> lock(m_mtx);
    m_loop = nullptr;
}

}